package com.gzdh.tang.dishrecognition.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gzdh.tang.comm.handler.IPayRuleHandler;
import com.gzdh.tang.comm.util.RedisUtil;
import com.gzdh.tang.comm.vo.Result;
import com.gzdh.tang.config.leshua.LeshuaPayUtils;
import com.gzdh.tang.config.weixin.WXEntity;
import com.gzdh.tang.config.weixin.WXPay;
import com.gzdh.tang.config.weixin.WXPayUtils;
import com.gzdh.tang.dishrecognition.model.PayModelReq;
import com.gzdh.tang.dishrecognition.service.LsPayService;
import com.gzdh.tang.modu.entity.Fk;
import com.gzdh.tang.modu.entity.MacMainpSbruan;
import com.gzdh.tang.modu.entity.MacMainpSbruanPayrule;
import com.gzdh.tang.modu.entity.Reserve;
import com.gzdh.tang.modu.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RequestMapping("dr/pay")
@RestController
@Slf4j
public class DrPayController {
    @Autowired
    MacMainpSbruanService macMainpSbruanService;

    @Autowired
    MacMainpSbruanPayruleService macMainpSbruanPayruleService;

    @Autowired
    MacMainpOrderService macMainpOrderService;

    @Autowired
    ReserveService reserveService;

    @Autowired
    LsPayService lsPayService;

    @Autowired
    FkService fkService;

    @Autowired
    RedisUtil redisUtil;

    /**
     * 发起支付
     *
     * @return
     */
    @PostMapping("consumptionTerminal/onLineConsume")
    public Result<Object> onLineConsume(@RequestBody JSONObject jsonObject) throws Exception {
        Result<Object> result = new Result<>();
        String deviceId = jsonObject.getString("deviceId");
        if (StringUtils.isEmpty(deviceId)) {
            return Result.error("参数错误，请核对参数是否正确");
        }
        MacMainpSbruan macMainpSbruan = macMainpSbruanService.getOne(new QueryWrapper<MacMainpSbruan>().lambda().eq(MacMainpSbruan::getMac, deviceId));
        if (macMainpSbruan == null) {
            return Result.error("设备未找到或者设备有误，请核对操作");
        }

        try {
            MacMainpSbruanPayrule macMainpSbruanPayrule = macMainpSbruanPayruleService.getById(macMainpSbruan.getPayRule());
            IPayRuleHandler ruleHandler = (IPayRuleHandler) Class
                    .forName(macMainpSbruanPayrule.getClassName())
                    .newInstance();
            JSONObject resJson = ruleHandler.toCardPay(jsonObject);
            jsonObject.putAll(resJson);
        } catch (RuntimeException e) {
            e.printStackTrace();
            result.setCode(500);
            result.setMessage(e.getMessage());
        }
        result.setResult(jsonObject);
        return result;
    }

    /**
     * 现金发起支付
     *
     * @return
     */
    @PostMapping("consumptionTerminal/onLineConsumeCash")
    public Result<Object> onLineConsumeCash(@RequestBody JSONObject jsonObject) throws Exception {
        Result<Object> result = new Result<>();
        String deviceId = jsonObject.getString("deviceId");
        if (StringUtils.isEmpty(deviceId)) {
            return Result.error("参数错误，请核对参数是否正确");
        }
        MacMainpSbruan macMainpSbruan = macMainpSbruanService.getOne(new QueryWrapper<MacMainpSbruan>().lambda().eq(MacMainpSbruan::getMac, deviceId));
        if (macMainpSbruan == null) {
            return Result.error("设备未找到或者设备有误，请核对操作");
        }
        try {
            MacMainpSbruanPayrule macMainpSbruanPayrule = macMainpSbruanPayruleService.getById(macMainpSbruan.getPayRule());
            IPayRuleHandler ruleHandler = (IPayRuleHandler) Class
                    .forName(macMainpSbruanPayrule.getClassName())
                    .newInstance();
            JSONObject resJson = ruleHandler.toCashPay(jsonObject);
            jsonObject.putAll(resJson);
        } catch (RuntimeException e) {
            log.error("报错信息:{}", e.toString());
            e.printStackTrace();
            result.setCode(500);
            result.setMessage(e.getMessage());
        }
        result.setResult(jsonObject);
        return result;
    }

    @PostMapping("consumptionTerminal/facePay")
    public Result<Object> facePay(@RequestBody JSONObject reqJson) {
        Result<Object> result = new Result<>();
        String deviceId = reqJson.getString("deviceId");
        if (StringUtils.isEmpty(deviceId)) {
            return Result.error("参数错误，请核对参数是否正确");
        }
        MacMainpSbruan macMainpSbruan = macMainpSbruanService.getOne(new QueryWrapper<MacMainpSbruan>().lambda().eq(MacMainpSbruan::getMac, deviceId));
        if (macMainpSbruan == null) {
            return Result.error("设备未找到或者设备有误，请核对操作");
        }
        try {
            MacMainpSbruanPayrule macMainpSbruanPayrule = macMainpSbruanPayruleService.getById(macMainpSbruan.getPayRule());
            IPayRuleHandler ruleHandler = (IPayRuleHandler) Class.forName(macMainpSbruanPayrule.getClassName()).newInstance();
            JSONObject resJson = ruleHandler.toFacePay(reqJson);
            result.setResult(resJson);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("系统错误：" + e.getMessage());
        }
        return result;
    }

    @PostMapping("consumptionTerminal/checkOrder")
    public Result<Object> checkOrder(@RequestBody JSONObject jsonObject) {
        Result<Object> result = new Result<>();
        System.out.println("查询订单" + jsonObject.toString());
        String orders = jsonObject.getString("orders");
        String sc = jsonObject.getString("sc");
        try {
            if("9".equals(sc)) { //乐刷支付查询
                Integer lsCanteenPayId = jsonObject.getInteger("lsCanteenPayId");
                String merchantId;
                String key;
                if (LeshuaPayUtils.getUseDatabaseConfig()) {
                    //使用乐刷数据库配置
                    Map<String, Object> payConfigMap = macMainpSbruanService.getCanteenPayConfig(lsCanteenPayId);
                    if(payConfigMap == null) {
                        throw new RuntimeException();
                    }
                    merchantId = String.valueOf(payConfigMap.get("mchId")).trim();
                    key = String.valueOf(payConfigMap.get("key")).trim();
                } else {
                    merchantId = LeshuaPayUtils.getMerchantId();
                    key = LeshuaPayUtils.getKey();
                }
                Map<String, String> resultMap = lsPayService.tradeOrderQuery(orders, merchantId, key);
                if(!"0".equals(resultMap.get("resp_code"))) {
                    jsonObject.put("msg", resultMap.get("resp_msg"));
                    jsonObject.put("wxPayStatus", "USERPAYING");
                }
                if(!"0".equals(resultMap.get("result_code"))) {
                    jsonObject.put("msg", resultMap.get("error_msg"));
                    jsonObject.put("wxPayStatus", "USERPAYING");
                }
                if("0".equals(resultMap.get("status"))) {
                    jsonObject.put("msg", "等待用户支付...");
                    jsonObject.put("wxPayStatus", "USERPAYING");
                } else if("2".equals(resultMap.get("status"))) {
                    jsonObject.put("wxPayStatus", "SUCCESS");
                    macMainpOrderService.judOrder(orders, resultMap.get("leshua_order_id"));
                } else {
                    jsonObject.put("wxPayStatus", "ERROR");
                }
            } else { //微信支付查询
                WXEntity wxEntity = new WXEntity();
                WXPay wxPay = new WXPay(wxEntity);
                Map<String, String> reqMap = new HashMap<>();
                reqMap.put("out_trade_no", orders);
                if (WXPayUtils.getSubmchMode() == 1) {
                    reqMap.put("sub_mch_id", WXPayUtils.getSubMchId());
                }
                Map<String, String> resMap = wxPay.orderQuery(reqMap);
                System.out.println(resMap.toString());
                log.info(resMap.toString());
                if (!"SUCCESS".equals(resMap.get("result_code")) && !"SUCCESS".equals(resMap.get("return_code"))) {
                    log.info("支付系统错误，需要进行查单");
                    jsonObject.put("wxPayStatus", "USERPAYING");

                } else if ("SUCCESS".equals(resMap.get("trade_state")) || "ACCEPT".equals(resMap.get("trade_state"))) {
                    //支付成功订单
                    jsonObject.put("wxPayStatus", "SUCCESS");
                    try {
                        macMainpOrderService.judOrder(orders);
                    } catch (RuntimeException e) {
                        e.printStackTrace();
                    }
                } else if ("USERPAYING".equals(resMap.get("trade_state")) || "USERPAYING".equals(resMap.get("err_code"))) {
                    jsonObject.put("wxPayStatus", "USERPAYING");
                } else {
                    jsonObject.put("wxPayStatus", "ERROR");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("支付失败");
        }
        if ("SUCCESS".equals(jsonObject.getString("wxPayStatus"))) {
            List<Reserve> reserveList = reserveService.list(new QueryWrapper<Reserve>().lambda().eq(Reserve::getZfserialnumber, orders));
            Fk fk = fkService.getOne(new QueryWrapper<Fk>().lambda().eq(Fk::getCardno, reserveList.get(0).getCardno()));
            jsonObject.put("fk", fk);
        }
        result.setResult(jsonObject);
        return result;
    }

    @PostMapping("consumptionTerminal/closeOrder")
    public Result<Object> closeOrder(@RequestBody JSONObject jsonObject) {
        Result<Object> result = new Result<>();
        log.info("关闭订单:" + jsonObject.toString());
        String orders = jsonObject.getString("orders");
        String sc = jsonObject.getString("sc");
        try {
            if("9".equals(sc)) { //乐刷支付
                throw new RuntimeException();
            } else { //微信支付
                WXEntity wxEntity = new WXEntity();
                WXPay wxPay = new WXPay(wxEntity);
                Map<String, String> reqMap = new HashMap<>();
                reqMap.put("out_trade_no", orders);
                if (WXPayUtils.getSubmchMode() == 1) {
                    reqMap.put("sub_mch_id", WXPayUtils.getSubMchId());
                }
                Map<String, String> resMap = wxPay.closeOrder(reqMap);
                log.info("请求结果" + resMap.toString());
                if (!"SUCCESS".equals(resMap.get("result_code")) && !"SUCCESS".equals(resMap.get("return_code"))) {
                    log.info("关闭订单错误");
                    jsonObject.put("wxPayStatus", "ERROR");
                } else {
                    jsonObject.put("wxPayStatus", "SUCCESS");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("关闭订单失败");
        }
        result.setResult(jsonObject);
        return result;
    }

    @PostMapping("refundProduct")
    public Result<Object> refundProduct(@RequestBody JSONObject jsonObject) {
        Result<Object> result = new Result<>();
        String orders = jsonObject.getString("orders");
        try {
            String tkOrders = reserveService.drRefundProduct(orders);
            Map<String, String> map = new HashMap<>();
            map.put("orders", tkOrders);
            redisUtil.addMap("redis-stream-01", map);
        } catch (RuntimeException e) {
            e.printStackTrace();
            return Result.error(e.getMessage());
        }
        return result;
    }


}
